package com.sgx.learning.luban.homework.attributes;

import com.sgx.learning.luban.homework.basictype.U2;
import com.sgx.learning.luban.homework.basictype.U4;
import com.sgx.learning.luban.homework.constantpool.ConstantPoolInfo;
import com.sgx.learning.luban.homework.constantpool.ConstantUtf8Info;

import java.io.IOException;
import java.io.InputStream;

public class AttributeHandlerUtils {

    public static AttributeInfo[] getAttribute(short count,InputStream is, ConstantPoolInfo[] constantPoolInfos) throws IOException {
        if(count == 0) {
            return null;
        }
        AttributeInfo[] res = new AttributeInfo[count];
        for (int i = 0; i < count; i++) {
            short attributeNameIndex = U2.read(is).getValue();
            int attributeLength = U4.read(is).getValue();
            ConstantUtf8Info attributeNameConstant = (ConstantUtf8Info) constantPoolInfos[attributeNameIndex - 1];
            AttributeInfo temp = switchAttr(is,attributeNameConstant.getBytesValue(),constantPoolInfos);
            temp.setAttributeNameIndex(attributeNameIndex);
            temp.setAttributeLength(attributeLength);
            res[i] = temp;
        }
        return res;
    }


    private static AttributeInfo switchAttr(InputStream is, String attributeType, ConstantPoolInfo[] constantPoolInfos) throws IOException {
        AttributeInfo attributeInfo = null;
        switch (attributeType) {
            case "ConstantValue":{
                attributeInfo = new ConstantValue();
            }break;
            case "Code":{
                attributeInfo = new Code();
            }break;
            case "LineNumberTable":{
                attributeInfo = new LineNumberTable();
            }break;
            case "LocalVariableTable":{
                attributeInfo = new LocalVariableTable();
            }break;
            case "Exceptions":{
                attributeInfo = new Exceptions();
            }break;
            case "SourceFile":{
                attributeInfo = new SourceFile();
            }break;
            case "LocalVariableTypeTable":{
                attributeInfo = new LocalVariableTypeTable();
            }break;
            case "StackMapTable":{
                attributeInfo = new StackMapTable();
            }
            default: break;
        }
        if(attributeInfo != null) {
            attributeInfo.read(is, constantPoolInfos);
        }
        return attributeInfo;
    }
}
